package auth

import (
	"fmt"
	"net/http"
	"strings"

	"gitee.com/hexug/devcloud/mcenter/apps/permission"
	"gitee.com/hexug/devcloud/mcenter/apps/token"
	"gitee.com/hexug/devcloud/mcenter/client/rpc"
	"gitee.com/hexug/devcloud/mcenter/common/logger"
	"gitee.com/hexug/devcloud/mcenter/consted"
	"github.com/emicklei/go-restful/v3"
)

func NewHttpAuther(client *rpc.ClientSet) *httpAuther {
	return &httpAuther{
		client: client,
	}
}

type httpAuther struct {
	client *rpc.ClientSet
}

func (h *httpAuther) AuthFunc(requset *restful.Request,
	response *restful.Response,
	next *restful.FilterChain) {
	//拿到所有的路由
	routers := requset.SelectedRoute()
	// 拿出字段中关于权限和认证的字段
	isAuth := routers.Metadata()["auth"]
	isPerm := routers.Metadata()["perm"]
	if routers != nil {
		if isAuth != nil && isAuth.(bool) {
			headerKey := requset.HeaderParameter(consted.TOKEN_HEADER_KEY)
			// fmt.Println(headerKey)
			tkSet := strings.Split(headerKey, " ")
			if len(tkSet) != 2 {
				response.WriteErrorString(http.StatusUnauthorized, "未携带合法令牌")
				return
			}
			username := tkSet[0]
			accessToken := tkSet[1]
			vtr := token.NewValidateTokenRequest(username)
			vtr.AccessToken = accessToken
			tk, err := h.client.Token().ValidateToken(requset.Request.Context(), vtr)
			if err != nil {
				logger.L().Error(err.Error())
				response.WriteErrorString(http.StatusUnauthorized, fmt.Sprintf("令牌无效 ERROE: %s", err.Error()))
				return
			}
			requset.SetAttribute(consted.TOKEN_HEADER_KEY, tk)
			if isPerm != nil && isPerm.(bool) {
				//新建请求参数
				cpmrq := permission.NewCheckPermissionRequest()
				cpmrq.UserId = tk.UserId
				cpmrq.ServiceId = h.client.Conf.ServerID
				cpmrq.Namespace = tk.Namespace
				cpmrq.HttpMethod = routers.Method()
				cpmrq.HttpPath = routers.Path()
				permis, err := h.client.Permission().CheckPermission(requset.Request.Context(), cpmrq)
				if err != nil {
					logger.L().Error(err.Error())
					response.WriteErrorString(http.StatusForbidden, fmt.Sprintf("权限校验失败 ERROE: %s", err.Error()))
					return
				}
				if !permis.HasPermisson {
					response.WriteErrorString(http.StatusForbidden, "暂无权限访问，若要访问，请联系管理员")
					return
				}
			}
		}
	}
	next.ProcessFilter(requset, response)
}
